const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ESLintWebpackPlugin = require('eslint-webpack-plugin')
const { ProgressPlugin, ProvidePlugin } = require('webpack')

module.exports = {
	entry: path.resolve(__dirname, '../', 'src/index.tsx'),
	// 打包文件出口
	output: {
		filename: 'static/js/[name].[chunkhash:8].js', // 每个输出js的名称 加上[chunkhash:8]
		// path: path.join(__dirname, '../dist'), // 打包结果输出路径
		clean: true, // webpack4 需要配置 clean-webpack-plugin 来删除 dist 文件, webpack5 内置了
		// publicPath: '/', // 打包后文件的公共前缀路径
	},

	resolve: {
		// extensions是webpack的resolve解析配置下的选项，在引入模块时不带文件后缀时，会来
		// 该配置数组里面依次添加后缀查找文件，因为ts不支持引入以 .ts, tsx为后缀的文件，所
		// 以要在extensions中配置，而第三方库里面很多引入js文件没有带后缀，所以也要配置下js
		extensions: ['.js', '.tsx', '.ts'],
		// 设置别名alias,设置别名可以让后续引用的地方减少路径的复杂度
		// 修改tsconfig.json,添加baseUrl和paths
		alias: {
			'@': path.join(__dirname, '../src'),
		},
		// 查找第三方模块只在本项目的node_modules中查找
		// 使用require和import引入模块时如果有准确的相对或者绝对路径,就会去按路径查询,如果引入的模块没有路径,
		// 会优先查询node核心模块,如果没有找到会去当前目录下node_modules中寻找,如果没有找到会查从父级文件夹
		// 查找node_modules,一直查到系统node全局模块。
		// 这样会有两个问题,一个是当前项目没有安装某个依赖,但是上一级目录下node_modules或者全局模块有安装,就也会引入成功,
		// 但是部署到服务器时可能就会找不到造成报错,另一个问题就是一级一级查询比较消耗时间。
		// 可以告诉 webpack搜索目录范围,来规避这两个问题
		modules: [path.resolve(__dirname, '../node_modules')],
	},
	module: {
		rules: [
			{
				// 配置 loader 解析 ts 和 jsx
				include: [path.resolve(__dirname, '../src')], // 缩小loader作用范围 只对项目src文件的ts,tsx进行loader解析
				test: /.(ts|tsx)$/, // 匹配.ts, tsx文件
				// thread-loader就是用来开启多进程解析loader的
				// 借助多核cpu开启多线程loader解析,可以极大地提升loader解析的速度
				use: ['babel-loader'],
			},
			// 如果node_moduels中也有要处理的语法，可以把js|jsx文件配置加上
			{
				test: /.(js|jsx)$/,
				use: 'babel-loader',
			},
			{ test: /\.(css|scss)$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
			{
				// 匹配图片文件
				test: /.(png|jpg|jpeg|gif|svg)$/,
				type: 'asset', // type选择asset
				parser: {
					dataUrlCondition: {
						maxSize: 10 * 1024, // 小于10kb转base64位
					},
				},
				generator: {
					filename: 'static/images/[name].[contenthash:8][ext]', // 文件输出目录和命名 加上[contenthash:8]
				},
			},
			{
				// 匹配字体图标文件
				test: /.(woff2?|eot|ttf|otf)$/,
				type: 'asset', // type选择asset
				parser: {
					dataUrlCondition: {
						maxSize: 10 * 1024, // 小于10kb转base64位
					},
				},
				generator: {
					filename: 'static/fonts/[name][ext]', // 文件输出目录和命名
				},
			},
			{
				// 匹配媒体文件
				test: /.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
				type: 'asset', // type选择asset
				parser: {
					dataUrlCondition: {
						maxSize: 10 * 1024, // 小于10kb转base64位
					},
				},
				generator: {
					filename: 'static/media/[name].[contenthash:8][ext]', // 文件输出目录和命名 加上[contenthash:8]
				},
			},
		],
	},
	plugins: [
		new ProgressPlugin(),
		new ProvidePlugin({
			React: path.resolve(__dirname, '../', 'node_modules/react/index.js'), // 全局
		}),
		// webpack需要把最终构建好的静态资源都引入到一个html文件中,这样才能在浏览器中运行,
		// html-webpack-plugin就是来做这件事情的
		new HtmlWebpackPlugin({
			title: 'hello', //对应打包后html文件 title
			template: path.resolve(__dirname, '../', 'public/index.html'),
			favicon: path.resolve(__dirname, '../', 'public/favicon.svg'),
			inject: true, // 自动注入静态资源
		}),
		new ESLintWebpackPlugin({
			eslintPath: 'eslint', //指定什么对代码进行校验
			extensions: ['js', 'jsx', 'ts', 'tsx'],
			exclude: ['node_modules'], //提升打包速度
			fix: false, //关闭自动修复
			formatter: 'stylish',
		}),
	],
}
